// 对象转换成查询字符串方法
function queryStringify(obj) {
  let str = ''

  for (let k in obj) {
    str += k + '=' + obj[k] + '&'
  }

  return str.slice(0, -1)
}

// 封装 ajax 的代码
function ajax(options = {}) {
  // 0. 从 options 内拿到所有的信息, 为了后面验证的时候使用方便
  const { url, method, async, data, headers, dataType, success } = options

  // 1. 验证 options 内的信息
  // 1-1. 验证 options 内的 url 信息是否填写了
  if (!url) throw new Error('url 为必填选项, 请传递此项内容, ^_^')

  // 1-2. 验证 method 信息
  if (!(method === undefined || /^(get|post)$/i.test(method))) throw new Error('method 目前只接受 "GET" 或者 "POST" 方式, 请期待更新 (#^.^#)')

  // 1-3. 验证 async 信息
  if (!(async === undefined || typeof async === 'boolean')) throw new Error('async 需要传递一个 "Boolean" 类型数据呦 O(∩_∩)O哈哈~')

  // 1-4. 验证 data 信息
  if (!(data === undefined || typeof data === 'string' || Object.prototype.toString.call(data) === '[object Object]'))  throw new Error('data 需要传递一个 "String" 或者 "Object" 类型数据 o(*￣︶￣*)o')

  // 1-5. 验证 headers 信息
  if (!(headers === undefined || Object.prototype.toString.call(headers) === '[object Object]')) throw new Error('headers 需要传递一个 "Object" 类型数据 o(*￣︶￣*)o')

  // 1-6. 验证 dataType 信息
  if (!(dataType === undefined || /^(json|string)$/i.test(dataType))) throw new Error('dataType 目前只接受 "json" 或者 "string" 两种值')

  // 1-7. 验证 success 信息
  if (!(success === undefined || typeof success === 'function')) throw new Error('success 需要传递一个 "Function" 类型数据')

  // 2. 准备一套默认值
  const _default = {
    url: url,
    method: method || 'GET',
    async: async ?? true,
    data: data || '',
    headers: { 'content-type': 'application/x-www-form-urlencoded', ...headers },
    dataType: dataType || 'string',
    success: success || function () {}
  }
  // 2-1. 调整一下 data 的值
  if (typeof _default.data === 'object') _default.data = queryStringify(_default.data)
  // 2-2. 调整一下 url 的值
  if (/^get$/i.test(_default.method) && _default.data) _default.url += '?' + _default.data

  // 3. 发送请求的代码
  const xhr = new XMLHttpRequest()

  xhr.open(_default.method, _default.url, _default.async)

  xhr.onload = function () {
    // 暂时直接打印结果
    const res = _default.dataType === 'string' ? xhr.responseText : JSON.parse(xhr.responseText)

    // 调用 _default.success 函数
    _default.success(res)
  }

  // 只要 headers 内有内容, 就设置到请求头上
  for (let k in _default.headers) xhr.setRequestHeader(k, _default.headers[k])

  // 分辨一下, 是 get 还是 post 请求
  ;/^get$/i.test(_default.method) ? xhr.send() : xhr.send(_default.data)
}

// 使用 Promise 语法, 对 ajax 进行二次封装
function pAjax(options = {}) {
  return new Promise((resolve, reject) => {
    ajax({
      url: options.url,
      data: options.data,
      async: options.async,
      method: options.method,
      headers: options.headers,
      dataType: options.dataType,
      success (res) {
        resolve(res)
      }
    })
  })
}






